﻿using System;
using System.Linq;
using Bots.DungeonBuddy.Attributes;
using Bots.DungeonBuddy.Helpers;
using CommonBehaviors.Actions;
using Styx.Helpers;
using Styx.Logic;
using Styx.Logic.Pathing;
using Styx.WoWInternals;
using TreeSharp;
using Styx;
using Styx.WoWInternals.WoWObjects;
using System.Collections.Generic;
using Action = TreeSharp.Action;

namespace Bots.DungeonBuddy.Dungeons.Cataclysm
{
    public class VortexPinnacle : Dungeon
    {
        #region Overrides of Dungeon

        /// <summary> The Map Id of this dungeon. This is the unique id for dungeons thats used to determine which dungeon, 
        /// the script belongs to </summary>
        /// <value>The map identifier.</value>
        public override uint DungeonId
        {
            get { return 311; }
        }

        public override WoWPoint Entrance
        {
            get { return new WoWPoint(-11524.55f, -2317.977f, 612.1523f); }
        }

        private CircularQueue<WoWPoint> _corpseRunBreadCrumb;
        public override CircularQueue<WoWPoint> CorpseRunBreadCrumb
        {
            get
            {
                return 
                    _corpseRunBreadCrumb ?? (_corpseRunBreadCrumb =
                    new CircularQueue<WoWPoint>
                        {
                            new WoWPoint(-11518.17f, -2166.622f, 513.0512f),
                            new WoWPoint(-11509.4f, -2285.51f, 614.3616f),
                            new WoWPoint(-11523.62f, -2319.026f, 613.0181f)
                        });
            }
        }

        public override bool IsFlyingCorpseRun
        {
            get { return true; }
        }

        public override void RemoveTargetsFilter(List<WoWObject> units)
        {
            units.RemoveAll(
                ret =>
                {
                    return false;
                });
        }

        public override void IncludeTargetsFilter(List<WoWObject> incomingunits, HashSet<WoWObject> outgoingunits)
        {
            foreach (var obj in incomingunits)
            {
                var unit = obj as WoWUnit;
                if (unit != null)
                {

                }
            }
        }

        public override void WeighTargetsFilter(List<Targeting.TargetPriority> units)
        {
            foreach (var priority in units)
            {
                var unit = priority.Object as WoWUnit;
                if (unit != null)
                {
                }
            }
        }


        #endregion

        #region Encounter Handlers

        /// <summary>
        /// Using 0 as BossEntry will make that composite the main logic for the dungeon and it will be called in every tick
        /// You can only have one main logic for a dungeon
        /// The context of the main composite is all units around as List<WoWUnit/>
        /// </summary>
        /// <returns></returns>
        [EncounterHandler(0)]
        public Composite RootLogic()
        {
            return
                new PrioritySelector(
                    ScriptHelpers.CreateTeleporterLogic(45455)/*,
                    new Decorator(
                        ctx => ScriptHelpers.Healer.IsMe && StyxWoW.Me.HasAura("Downwind of Altairus"),
                        new Sequence(
                            new Action(ctx => Logger.Write("[Dungeon General] Facing away from the downwind")),
                            new Action(ctx => StyxWoW.Me.SetFacing(StyxWoW.Me.Rotation + (float)Math.PI)),
                            new ActionAlwaysFail()))*/
                        
                    );
        }

        [EncounterHandler(43875, "Asaad")]
        public Composite AsaadLogic()
        {
            const int unstableGroundingField = 86911;
            return
                new PrioritySelector(
                    new Decorator(
                        ctx => ((WoWUnit)ctx).CastingSpellId == unstableGroundingField && ScriptHelpers.Tank != null,
                        new Sequence(
                            new Action(ctx => Logger.Write("[Asaad Encounter] Running inside grounding field")),
                            new Action(ctx => Navigator.PlayerMover.MoveTowards(ScriptHelpers.Tank.Location))))

                    );
        }

        [EncounterHandler(43878, "Grand Vizier Ertan")]
        public Composite ErtanLogic()
        {
            const int vortexId = 46007;
            return
                new PrioritySelector(
                        ctx =>
                            {
                                var vortexes =
                                            ObjectManager.GetObjectsOfType<WoWUnit>(false, false).Where(
                                                u => u.Entry == vortexId && u.Location.DistanceSqr(((WoWUnit)ctx).Location) > 20 * 20 
                                                     && u.IsSafelyFacing((WoWUnit)ctx, 60));
                                
                                if (vortexes.Count() == 0)
                                    return ctx;

                                var firstTwo = vortexes.OrderBy(u => u.DistanceSqr).Take(2);

                                return firstTwo.Select(v => v.Location).Aggregate((p1, p2) => p1 + p2) / firstTwo.Count();
                            },
                    new Decorator(
                        ctx => ctx is WoWPoint,
                        new Sequence(
                            new Action(ctx => Logger.Write("[Ertan Encounter] Avoiding Vortexes")),
                            new Action(ctx => Navigator.PlayerMover.MoveTowards((WoWPoint)ctx)),
                            new DecoratorContinue(
                                ctx => !ScriptHelpers.Healer.IsMe,
                                new WaitContinue(
                                    10,
                                    ctx => false,
                                    new ActionAlwaysSucceed())),
                            new WaitContinue(
                                3, 
                                ctx => false, 
                                new ActionAlwaysSucceed())
                            )),

                    new Decorator(
                        ctx => ctx is WoWUnit && ((WoWUnit)ctx).DistanceSqr > 15 * 15,
                        new Sequence(
                            new Action(ctx => Logger.Write("[Ertan Encounter] Getting closer to the boss")),
                            new Action(ctx => Navigator.PlayerMover.MoveTowards(((WoWUnit)ctx).Location))))
                    
                    );
        }

        #endregion
    }
}
